﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.IO;

using BizElements.Generator.Properties;
using BizElements.TemplateEngine;

namespace BizElements.Generator
{
    public partial class TemplateCtl : UserControl
    {
        bool isInDesignMode;

        public TemplateCtl()
        {
            this.isInDesignMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
            InitializeComponent();
        }

        #region Properties, events, delegates.

        public string Caption
        {
            get { return this.uiBox.Text; }
            set { this.uiBox.Text = value; }
        }

        public string DefaultTemplateFileName { get; set; }

        [Browsable(false)]
        public ITemplate Template
        {
            get { return this.uiVariables.Template; }
        }

        [Browsable(false)]
        public IVariableValueBus VariableBus
        {
            get { return this.uiVariables.VariableBus; }
            set { this.uiVariables.VariableBus = value; }
        }

        public bool ChangeTemplateEnabled
        {
            get { return this.uiOpenTemplate.Enabled; }
            set { this.uiOpenTemplate.Enabled = value; }
        }

        public string TemplateFile
        {
            get { return this.uiTemplatePath.Text.Trim(); }
        }

        public string FileFilter
        {
            get { return this.uiTemplateFile.Filter; }
            set { this.uiTemplateFile.Filter = value; }
        }

        #endregion

        #region Load - set defaults.

        private void TemplateCtl_Load(object sender, EventArgs e)
        {
            if (this.DesignMode || this.isInDesignMode)
                return;

            if (!IsTemplateAlreadySetAndLoaded())
            {
                SetDefaultFolderAndFile();
                TryLoadSelectedTemplate();
            }
            else
            {
                if (string.IsNullOrEmpty(this.uiTemplateFile.InitialDirectory) || (this.uiTemplateFile.InitialDirectory == Settings.Default.TemplateCtl_DefaultTemplateFolder))
                    this.uiTemplateFile.InitialDirectory = GetDefaultTemplateFolder();
            }
        }

        private bool IsTemplateAlreadySetAndLoaded()
        {
            bool isFileSelected = !string.IsNullOrEmpty(this.uiTemplatePath.Text);
            bool isTemplateLoaded = (this.Template != null);
            return (isFileSelected && isTemplateLoaded);
        }

        private void SetDefaultFolderAndFile()
        {            
            this.uiTemplateFile.InitialDirectory = GetDefaultTemplateFolder();
            if (!string.IsNullOrEmpty(this.DefaultTemplateFileName))
                this.uiTemplatePath.Text = this.uiTemplateFile.InitialDirectory + "\\" + this.DefaultTemplateFileName;
        }

        private static string GetDefaultTemplateFolder()
        {
            string defaultDir;
            string cfgValue = Settings.Default.TemplateCtl_DefaultTemplateFolder;
            if (Path.IsPathRooted(cfgValue))
                defaultDir = cfgValue;
            else
                defaultDir = Path.Combine(IoUtil.GetExecutableDirectory(), cfgValue);

            return defaultDir;
        }

        private static string GetDefaultTemplateFolderRelativePath()
        {
            return Settings.Default.TemplateCtl_DefaultTemplateFolder;
        }

        #endregion

        private void uiOpenTemplate_Click(object sender, EventArgs e)
        {
            var answer = this.uiTemplateFile.ShowDialog();
            if (answer == DialogResult.OK)
            {
                this.uiTemplatePath.Text = this.uiTemplateFile.FileName;
                TryLoadSelectedTemplate();
            }
        }

        private void TryLoadSelectedTemplate()
        {
            string templatePath = this.uiTemplatePath.Text.Trim();
            if (File.Exists(templatePath))
            {
                Template template = new Template();
                template.ReadXml(templatePath);
                SetNewTemplateIfChanged(template);
            }
            else
            {
                MessageBox.Show(string.Format(Messages.TemplateCtl_TemplateFileDoesntExistX, templatePath));
            }
        }

        private void SetNewTemplateIfChanged(ITemplate value)
        {
            bool hasChanged;
            if ((value == null) || (this.Template == null))
                hasChanged = true;
            else
                hasChanged = (this.Template.XmlContent != value.XmlContent);

            if (hasChanged)
            {
                this.uiVariables.Template = value;
                if (value != null)
                    this.uiBox.Text = value.Header.Title + " - " + value.Header.Description;
            }
        }

        #region Settings.

        public void ReadSettings(string keyPrefix, BizElementsSettings settings)
        {
            if (!string.IsNullOrEmpty(settings[keyPrefix + "_InitialFolder"]))
                this.uiTemplateFile.InitialDirectory = settings[keyPrefix + "_InitialFolder"];

            if (!string.IsNullOrEmpty(settings[keyPrefix + "_File"]))
            {
                string absOrRelativePath = settings[keyPrefix + "_File"];
                this.uiTemplatePath.Text = ToAbsolutePath(absOrRelativePath);
            }

            TryLoadSelectedTemplate();
            this.uiVariables.ReadSettings(keyPrefix, settings);
        }

        public void WriteSettings(string keyPrefix, BizElementsSettings settings)
        {
            settings[keyPrefix + "_InitialFolder"] = TryGetRelativeInitialFolder(this.uiTemplateFile.InitialDirectory);
            settings[keyPrefix + "_File"] = TryGetRelativeTemplateFilePath(this.uiTemplatePath.Text.Trim());

            this.uiVariables.WriteSettings(keyPrefix, settings);
        }

        private static string TryGetRelativeTemplateFilePath(string absolutePath)
        {
            string absPathToDefaultDir = GetDefaultTemplateFolder();
            absPathToDefaultDir = TextUtil.EnsureSuffix(absPathToDefaultDir, "\\");
            if (absolutePath.StartsWith(absPathToDefaultDir, /*ignore case*/ true, null))
            {
                string fileName = TextUtil.RemovePrefix(absolutePath, absPathToDefaultDir);
                string relPathToDefaultDir = GetDefaultTemplateFolderRelativePath();
                relPathToDefaultDir = TextUtil.EnsureSuffix(relPathToDefaultDir, "\\");
                return relPathToDefaultDir + fileName;
            }
            else
            {
                return absolutePath;
            }
        }

        private static string TryGetRelativeInitialFolder(string absPath)
        {
            string absPathToDefaultDir = TextUtil.RemoveSuffix(absPath, GetDefaultTemplateFolderRelativePath());
            absPathToDefaultDir = TextUtil.EnsureSuffix(absPathToDefaultDir, "\\");
            if (absPath.StartsWith(absPathToDefaultDir, /*ignore case*/ true, null))
            {
                return TextUtil.RemovePrefix(absPath, absPathToDefaultDir);
            }
            else
            {
                return absPath;
            }
        }

        private static string ToAbsolutePath(string path)
        {
            string absPath;
            if (Path.IsPathRooted(path))
                absPath = path;
            else
                absPath = Path.Combine(IoUtil.GetExecutableDirectory(), path);

            return absPath;                
        }

        #endregion        
    }
}
